home *** CD-ROM | disk | FTP | other *** search
- #include <linux/ipx.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include "internal.h"
- #include "netconf.h"
- #include "netconf.m"
-
- NETCONF_HELP_FILE help_ipx("ipx");
- static CONFIG_FILE f_ipx_inter (PROC_NET_IPX_INTER,help_ipx
- ,CONFIGF_PROBED|CONFIGF_OPTIONNAL);
-
- static char *tbframe[]={
- "802.2","802.3","EtherII","snap"
- };
- extern char *tb_netdevices[];
-
- static const char IPX[]="ipx";
- static const char INTERNAL_NETNUM[]="internal_netnum";
- static const char INTERNAL_NODENUM[]="internal_nodenum";
- static const char PRIMARY_AUTO[]="primary_auto";
- static const char FRAME_AUTO[]="frame_auto";
- static const char ACTIVE[]="active";
-
- /*
- Load the IPX configuration from /etc/conf.linuxconf
- */
- PUBLIC IPX_INFO::IPX_INFO()
- {
- ipx_active = linuxconf_getvalnum (IPX,ACTIVE,0);
- internal_netnum = linuxconf_getvalnum (IPX,INTERNAL_NETNUM,0);
- internal_nodenum = linuxconf_getvalnum (IPX,INTERNAL_NODENUM,0);
- primary_auto = linuxconf_getvalnum (IPX,PRIMARY_AUTO,1);
- frame_auto = linuxconf_getvalnum (IPX,FRAME_AUTO,1);
- for (int i=0; i<NB_ETH; i++){
- IPX_INTER_INFO *itf = &a[i];
- for (int f=0; f<NB_IPX_FRAME_TYPE; f++){
- IPX_FRAME_INFO *fra = &itf->frames[f];
- fra->name = tb_netdevices[i];
- fra->netnum = 0;
- fra->primary = 0;
- fra->active = 0;
- char buf[20];
- sprintf (buf,"%s-%s",tb_netdevices[i],tbframe[f]);
- const char *val = linuxconf_getval (IPX,buf);
- if (val != NULL){
- int active,primary;
- sscanf (val,"%x %d %d",&fra->netnum,&active,&primary);
- fra->primary = (char)primary;
- fra->active = (char)active;
- }
- }
- }
- }
- /*
- Probe the IPX's "auto_configuration" flags in the kernel.
- */
- PRIVATE void IPX_INFO::probe_auto()
- {
- /* #Specification: netconf / ipx / ioctl SIOCIPXCFGDATA
- linuxconf use the ioctl SIOCIPXCFGDATA to extract the
- status of the auto configuration flags of the IPX network.
- */
- ipx_config_data data;
- int s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
- if (s < 0) {
- xconf_error (MSG_U(E_IPXSOCKET
- ,"Can't open IPX control socket\n"
- "Looks ODD to me.\n"
- "Maybe linuxconf is incompatible with the kernel release"));
- }else if (ioctl(s, SIOCIPXCFGDATA, &data) == 0){
- primary_auto = data.ipxcfg_auto_select_primary != 0;
- frame_auto = data.ipxcfg_auto_create_interfaces != 0;
- }
- }
-
- /*
- Load the IPX configuration from the kernel.
- */
- PUBLIC IPX_INFO::IPX_INFO(CONFIG_FILE &f)
- {
- primary_auto = 0;
- frame_auto = 0;
- internal_netnum = 0;
- internal_nodenum = 0;
- ipx_active = 0;
- int i;
- for (i=0; i<NB_ETH; i++){
- IPX_INTER_INFO *itf = &a[i];
- for (int f=0; f<NB_IPX_FRAME_TYPE; f++){
- IPX_FRAME_INFO *fra = &itf->frames[f];
- fra->name = tb_netdevices[i];
- fra->netnum = 0;
- fra->primary = 0;
- fra->active = 0;
- }
- }
- FILE *fin = f.fopen ("r");
- if (fin != NULL){
- /* #Specification: netconf / ipx / file /proc/net/ipx_interface
- Linuxconf interprets the file /proc/net/ipx_interface
- to extract the running configuration in the kernel.
- The first line of this file is a header. The other lines
- have the following format.
-
- #
- network node primary dev frame
- #
- */
- probe_auto();
- char buf[300];
- int format_err = 1;
- // Skip the header
- if (fgets(buf,sizeof(buf)-1,fin)!=NULL){
- format_err = 0;
- while (fgets(buf,sizeof(buf)-1,fin)!=NULL){
- char network[100], node[100],primary[100],dev[100],frame[100];
- if (sscanf (buf,"%s %s %s %s %s"
- ,network,node,primary,dev,frame)!=5){
- format_err = 1;
- break;
- }else if (stricmp(dev,"Internal")==0){
- sscanf (network,"%x",&internal_netnum);
- sscanf (node,"%x",&internal_nodenum);
- }else{
- for (i=0; i<NB_ETH; i++){
- if (stricmp(dev,tb_netdevices[i])==0){
- IPX_INTER_INFO *itf = &a[i];
- int f;
- for (f=0; f<NB_IPX_FRAME_TYPE; f++){
- if (stricmp(frame,tbframe[f])==0){
- IPX_FRAME_INFO *fra = &itf->frames[f];
- fra->active = 1;
- fra->primary = stricmp(primary,"Yes")==0;
- sscanf (network,"%x",&fra->netnum);
- break;
- }
- }
- if (f==NB_IPX_FRAME_TYPE) format_err = 1;
- break;
- }
- }
- if (i==NB_ETH) format_err = 1;
- }
- }
- }
- fclose (fin);
- if (format_err){
- xconf_error (MSG_U(E_IPXFORMAT
- ,"Invalid format of file %s\n"
- "Can't manage IPX properly\n")
- ,f_ipx_inter.getpath());
- }
- }
- }
-
-
- PUBLIC int IPX_INFO::save()
- {
- linuxconf_replace (IPX,ACTIVE,ipx_active);
- linuxconf_replace (IPX,INTERNAL_NETNUM,internal_netnum);
- linuxconf_replace (IPX,INTERNAL_NODENUM,internal_nodenum);
- linuxconf_replace (IPX,PRIMARY_AUTO,primary_auto);
- linuxconf_replace (IPX,FRAME_AUTO,frame_auto);
- for (int i=0; i<NB_ETH; i++){
- IPX_INTER_INFO *itf = &a[i];
- for (int f=0; f<NB_IPX_FRAME_TYPE; f++){
- IPX_FRAME_INFO *fra = &itf->frames[f];
- char buf[20];
- sprintf (buf,"%s-%s",tb_netdevices[i],tbframe[f]);
- char val[100];
- sprintf (val,"%x %d %d",fra->netnum,fra->active,fra->primary);
- linuxconf_replace (IPX,buf,val);
- }
- }
- return linuxconf_save();
- }
-
-
- PUBLIC int IPX_INFO::edit()
- {
- DIALOG dia;
-
- dia.newf_chk (MSG_U(F_IPXENABLE,"Enable"),ipx_active
- ,MSG_U(F_IPXNETWORK,"IPX networking"));
-
-
- char f_primary = primary_auto ? 0 : 100; // 100 is anything different 0
- dia.newf_radio (MSG_U(F_IPXAUTOCONFIG,"Autoconfigure")
- ,f_primary,0,MSG_U(F_PRIMARY,"primary"));
- dia.newf_chk (MSG_R(F_IPXAUTOCONFIG),frame_auto
- ,MSG_U(F_FRAMETYPES,"interfaces frame types"));
- int i;
- for (i=0; i<NB_ETH; i++){
- IPX_INTER_INFO *itf = &a[i];
- static const char *tbmsg[]={
- MSG_R(T_FIRSTETH),
- MSG_R(T_SECONDETH),
- MSG_R(T_THIRDETH),
- MSG_R(T_FOURTHETH)
- };
- dia.newf_title ("",tbmsg[i]);
- for (int f=0; f<NB_IPX_FRAME_TYPE; f++){
- if (f != 0) dia.newf_title ("","-");
- IPX_FRAME_INFO *fra = &itf->frames[f];
- dia.newf_chk (MSG_U(F_FRAMETYPE,"Frame type"),fra->active,tbframe[f]);
- int id = i*NB_IPX_FRAME_TYPE+f+1;
- if (fra->primary) f_primary = id;
- dia.newf_radio ("",f_primary,id,MSG_U(F_ISPRIMARY
- ,"is the primary interface"));
- dia.newf_num (MSG_U(F_IPXNETNUM,"Network number(0=probe)"),fra->netnum);
- }
- }
- dia.newf_title ("",MSG_U(T_IPXINTERNAL,"Internal network"));
- dia.newf_num (MSG_U(F_IPXINTERNALNETNUM,"Internal network number(opt)")
- ,internal_netnum);
- dia.newf_num (MSG_U(F_IPXINTERNALNODENUM,"Internal node number(opt)")
- ,internal_nodenum);
- int nof = 0;
- int ret = -1;
- while (1){
- MENU_STATUS code = dia.edit (MSG_U(T_IPXCONF,"IPX interface configuration")
- ,MSG_U(I_IPXCONF,"You must associate a frame type with\n"
- "a network devices and a network number\n"
- "For one device, it is possible to have several\n"
- "combination of frame and network number.\n"
- "Most linux client machine (IPX client) will be happy\n"
- "by selecting the \"autoconfigure\" choices.")
- ,help_ipx
- ,nof);
- if (code == MENU_CANCEL || code == MENU_ESCAPE){
- dia.restore();
- break;
- }else if (code == MENU_ACCEPT){
- ret = 0;
- //we have to walk the structures to set/unset the primary field
- //of each potential IPX interface
- //Ony one can be primary
- primary_auto = f_primary == 0;
- for (i=0; i<NB_ETH; i++){
- IPX_INTER_INFO *itf = &a[i];
- for (int f=0; f<NB_IPX_FRAME_TYPE; f++){
- IPX_FRAME_INFO *fra = &itf->frames[f];
- int id = i*NB_IPX_FRAME_TYPE+f+1;
- fra->primary = f_primary == id;
- }
- }
- break;
- }
- }
- return ret;
- }
-
-
- void ipx_edit()
- {
- IPX_INFO ipx;
- if (ipx.edit()==0) ipx.save();
- }
-
- /*
- Activate/update conditionnally the IPX interface configuration
- */
- PUBLIC int IPX_INFO::set()
- {
- int ret = 0;
- IPX_INFO cur(f_ipx_inter);
- if (ipx_active){
- if (primary_auto != cur.primary_auto
- || frame_auto != cur.frame_auto){
- char buf[100];
- sprintf (buf,"--auto_interface=%s --auto_primary=%s"
- ,frame_auto ? "on" : "off"
- ,primary_auto ? "on" : "off");
- netconf_system_if("ipx_configure",buf);
- }
- for (int i=0; i<NB_ETH; i++){
- const char *devname = tb_netdevices[i];
- int dev_exist = devlist_devexist (devname);
- IPX_INTER_INFO *itf = &a[i];
- IPX_INTER_INFO *cur_itf = &cur.a[i];
- for (int f=0; f<NB_IPX_FRAME_TYPE; f++){
- IPX_FRAME_INFO *fra = &itf->frames[f];
- IPX_FRAME_INFO *cur_fra = &cur_itf->frames[f];
- /* #Specification: netconf / ipx / managing
- Activating or not IPX interface is tricky. First we
- probe the current configuration (running) and compare
- it with the intend configuration. The problem comes
- from the fact that IPX interface can configure themselves
- from network trafic (if frame_auto is on).
-
- The idea here is to find out if the configuration
- of one interface is different from what is currently
- running. If so, then we must configure or unconfigure
- the interface. If we must unconfigure the interface
- we must check first if frame_auto is on. If so, the
- interface has been configured by itself, and we
- are not allowed to remove it.
- */
- int do_something = 0;
- if (fra->active != cur_fra->active){
- if (fra->active || !frame_auto){
- do_something = 1;
- }
- }else if (fra->active){
- if (fra->netnum != cur_fra->netnum
- && fra->netnum != 0){
- do_something = 1;
- }
- if (fra->primary != cur_fra->primary
- && (fra->primary || !primary_auto)){
- do_something = 1;
- }
- }
- if (do_something){
- char buf[100];
- if (fra->active){
- int len = sprintf (buf,"add %s %s %s"
- ,fra->primary ? "-p" : ""
- ,devname,tbframe[f]);
- if (fra->netnum != 0){
- sprintf (buf+len," %x",fra->netnum);
- }
- if (!dev_exist){
- ret |= device_insmod (devname);
- dev_exist = 1; // Shut off for next run
- }
- }else{
- sprintf (buf,"del %s %s",devname,tbframe[f]);
- }
- ret |= netconf_system_if ("ipx_interface",buf);
- }
- }
- }
- if (internal_netnum != cur.internal_netnum
- || internal_nodenum != cur.internal_nodenum){
- if (internal_netnum != 0){
- char buf[100];
- sprintf (buf,"add %x %x",internal_netnum,internal_nodenum);
- ret |= netconf_system_if ("ipx_internal_net",buf);
- }else{
- ret |= netconf_system_if ("ipx_internal_net","del");
- }
- }
- }
- return ret;
- }
-
- int ipx_set ()
- {
- IPX_INFO info;
- return info.set();
- }
-
-